package com.lanyu.community.api.controller;


import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.http.ProtocolType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.aliyuncs.sts.model.v20150401.AssumeRoleRequest;
import com.aliyuncs.sts.model.v20150401.AssumeRoleResponse;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.shiro.SecurityUtils;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;


import com.aliyuncs.exceptions.ClientException;
import com.lanyu.community.api.constat.CommonConstant;
import com.lanyu.community.api.entity.User;
import com.lanyu.community.api.service.ISysBaseAPI;
import com.lanyu.community.api.service.ISysUserService;
import com.lanyu.community.api.shiro.DefContants;
import com.lanyu.community.api.shiro.JwtUtil;
import com.lanyu.community.api.shiro.SysLoginModel;
import com.lanyu.community.api.util.PasswordUtil;
import com.lanyu.community.api.util.RedisUtil;
import com.lanyu.community.api.util.Result;
import com.lanyu.community.api.util.oConvertUtils;
import com.lanyu.mybatis.dao.entity.UcenterUserinfo;

import cn.hutool.core.util.RandomUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;

/**
 * @Author suibin
 * @since 2018-12-17
 */
@RestController
@RequestMapping("/sys")
@Api(tags="用户登录")
@Slf4j
public class LoginController {
	@Autowired
	private ISysUserService sysUserService;
	@Autowired
	private ISysBaseAPI sysBaseAPI;
	//@Autowired
	//private ISysLogService logService;
	@Autowired
    private RedisUtil redisUtil;
	//@Autowired
    //private ISysDepartService sysDepartService;


	@RequestMapping(value = "/getOssSTS", method = RequestMethod.POST)
	@ApiOperation("获取STS")
	public AssumeRoleResponse buildAliyunSTSCredentials() throws ClientException {

		Object object = redisUtil.get(CommonConstant.PREFIX_STS_TOKEN);
		if (object != null) {
			return (AssumeRoleResponse) object;
		}else {
			// STS
			DefaultProfile.addEndpoint("", "", "Sts", "sts.cn-hongkong.aliyuncs.com");
			IClientProfile profile = DefaultProfile.getProfile("", "LTAI4Fezefb7xCmVEjKv5LHr", "TSRZRND8oCrY1fpoi4j5uTsNQ84CMq");
			DefaultAcsClient client = new DefaultAcsClient(profile);

			final AssumeRoleRequest request = new AssumeRoleRequest();
			request.setMethod(MethodType.POST);
			request.setProtocol(ProtocolType.HTTPS);
			request.setDurationSeconds(60 * 60 * 1L);
			request.setRoleArn("acs:ram::31549800:role/1111111j");  // 要扮演的角色ID
			request.setRoleSessionName("community-app");
			// request.setPolicy(policy);

			// 生成临时授权凭证
			final AssumeRoleResponse response = client.getAcsResponse(request);

			redisUtil.set(CommonConstant.PREFIX_STS_TOKEN, response);
			// 设置超时时间
			redisUtil.expire(CommonConstant.PREFIX_STS_TOKEN, 3000);

			String appKey = response.getCredentials().getAccessKeyId();  // 临时凭据AccessKeyId
			String appSecret = response.getCredentials().getAccessKeySecret();  // 临时凭据AccessKeySecret
			String securityToken = response.getCredentials().getSecurityToken();
			String expiration = response.getCredentials().getExpiration();

		return response;
		}
	}

	@RequestMapping(value = "/login", method = RequestMethod.POST)
	@ApiOperation("登录接口")
	public Result<JSONObject> login(@RequestBody SysLoginModel sysLoginModel) throws Exception {
		Result<JSONObject> result = new Result<JSONObject>();
		String username = sysLoginModel.getUsername();
		String password = sysLoginModel.getPassword();
		//update-begin--Author:scott  Date:20190805 for：暂时注释掉密码加密逻辑，有点问题
		//前端密码加密，后端进行密码解密
		//password = AesEncryptUtil.desEncrypt(sysLoginModel.getPassword().replaceAll("%2B", "\\+")).trim();//密码解密
		//update-begin--Author:scott  Date:20190805 for：暂时注释掉密码加密逻辑，有点问题

		//1. 校验用户是否有效
		UcenterUserinfo sysUser = sysUserService.getUserByName(username);
		result = sysUserService.checkUserIsEffective(sysUser);
		if(!result.isSuccess()) {
			return result;
		}
		
		//2. 校验用户名或密码是否正确
		String userpassword = PasswordUtil.encrypt(username, password, sysUser.getSalt());
		String syspassword = sysUser.getPwd();
		if (!syspassword.equals(userpassword)) {
			result.error500("用户名或密码错误");
			return result;
		}
				
		//用户登录信息
		userInfo(sysUser, result);
		sysBaseAPI.addLog("用户名: " + username + ",登录成功！", CommonConstant.LOG_TYPE_1, null);

		return result;
	}
	
	/**
	 * 退出登录
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping(value = "/logout", method = RequestMethod.POST)
	@ApiOperation("退出用户接口")
	public Result<Object> logout(HttpServletRequest request,HttpServletResponse response) {
		//用户退出逻辑
	    String token = request.getHeader(DefContants.X_ACCESS_TOKEN);
	    if(oConvertUtils.isEmpty(token)) {
	    	return Result.error("退出登录失败！");
	    }
	    String username = JwtUtil.getUsername(token);
	    //UcenterUserinfo sysUser = sysUserService.getUserByName(username);
	    //if(sysUser!=null) {
	    	sysBaseAPI.addLog("用户名: "+username+",退出成功！", CommonConstant.LOG_TYPE_1, null);
	    	log.info(" 用户名:  "+username+",退出成功！ ");
	    	//清空用户Token缓存
	    	redisUtil.del(CommonConstant.PREFIX_USER_TOKEN + username);
	    	//清空用户权限缓存：权限Perms和角色集合
	    	//redisUtil.del(CommonConstant.LOGIN_USER_CACHERULES_ROLE + username);
	    	//redisUtil.del(CommonConstant.LOGIN_USER_CACHERULES_PERMISSION + username);
	    	return Result.ok("退出登录成功！");
	    //}else {
	    //	return Result.error("无效的token");
	    //}
	}
	@ApiOperation(value = "注册用户", notes = "")
	@RequestMapping(value = "/register", method = RequestMethod.POST)
	@ResponseBody
	public Result register(
			@RequestParam("username") String username,
			@RequestParam("mobile") String mobile,
			@RequestParam("nickname") String nickname,
			@RequestParam("age") String age,
			@RequestParam("addr") String addr,
			@RequestParam("head") String head,
			@RequestParam("password") String password,
			@RequestParam("cpassword") String cpassword,
			@RequestParam("sex") String sex
			) throws Exception {
		Result result=new Result();
		
		if(password.equals(cpassword)) {



			UcenterUserinfo user=new UcenterUserinfo();
			user.setUsername(username);
			user.setMobile(mobile);
			user.setNickname(nickname);
			user.setAge(age);
			user.setAddr(addr);
			user.setAddr(addr);
			user.setHead(head);
			user.setSex(sex);
			user.setCreateTime(new Date());

			String salt = oConvertUtils.randomGen(8);
			user.setSalt(salt);
			String passwordEncode = PasswordUtil.encrypt(username, password, salt);
			user.setPwd(passwordEncode);
			user.setStatus(0);


			if(sysUserService.save(user)) {
				result.setResult("1");
				result.setMessage("注册成功！");
				
			}else {
				result.error500("接口异常");
			}
		}else {
			result.setResult("0");
			result.setMessage("俩次密码不相同！");
		
		}
		return result;
	}

	@CacheEvict(value = "person:persondetail_cache",key = "'params_'+#uid")
	@ApiOperation(value = "更新用户", notes = "")
	@RequestMapping(value = "/updateUser", method = RequestMethod.POST)
	@ResponseBody
	public Result updateUser(
			//@RequestParam("username") String username,
			@RequestParam(value="mobile", required=false) String mobile,
			@RequestParam(value="nickname", required=false) String nickname,
			@RequestParam(value="age", required=false) String age,
			@RequestParam(value="addr", required=false) String addr,
			@RequestParam(value="head", required=false) String head,
			//@RequestParam("password") String password,
			//@RequestParam("cpassword") String cpassword,
			@RequestParam(value="loginame", required=false) String loginame,
			@RequestParam(value="token", required=true) String token,
			@RequestParam(value="sex", required=false) String sex,
			@RequestParam(value="uid", required=true) String uid
	) throws Exception {

		Result result=new Result();

		Object _token=redisUtil.get(CommonConstant.PREFIX_USER_TOKEN + loginame);

		if(!_token.equals(token)) {
			result.error500("token认证失败");
			return result;
		}
		UcenterUserinfo user=new UcenterUserinfo();

		if(!mobile.equals("")){
			user.setMobile(mobile);
		}
		if(!nickname.equals("")) {
			user.setNickname(nickname);
		}
		if(!age.equals("")) {
			user.setAge(age);
		}
		if(!addr.equals("")) {
			user.setAddr(addr);
		}
		if(!head.equals("")) {
			user.setHead(head);
		}

		if(!sex.equals("")) {
			user.setSex(sex);
		}
		user.setUpdateTime(new Date());


		Wrapper<UcenterUserinfo> wrapperq=new QueryWrapper<UcenterUserinfo>()
				.eq("uid",uid)
				;
		if(sysUserService.update(user,wrapperq)) {
			result.setResult("1");
			result.setMessage("更新成功！");

		}else {
			result.error500("接口异常");
		}

		return result;
	}

	@ApiOperation(value = "更新用户密码", notes = "")
	@RequestMapping(value = "/updateUserPwd", method = RequestMethod.POST)
	@ResponseBody
	public Result updateUserPwd(
			@RequestParam("password") String password,
			@RequestParam("cpassword") String cpassword,
			@RequestParam("oldpassword") String opassword,
			@RequestParam("loginame") String loginame,
			@RequestParam("uid") String uid
	) throws Exception {
		Result result=new Result();

		//1. 校验用户是否有效
		UcenterUserinfo sysUser = sysUserService.getUserByName(loginame);
		result = sysUserService.checkUserIsEffective(sysUser);
		if(!result.isSuccess()) {
			return result;
		}

		//2. 校验用户名或密码是否正确
		String userpassword = PasswordUtil.encrypt(loginame, opassword, sysUser.getSalt());
		String syspassword = sysUser.getPwd();
		if (!syspassword.equals(userpassword)) {
			result.error500("用户名或密码错误");
			return result;
		}

		if(password.equals(cpassword)) {

			UcenterUserinfo user=new UcenterUserinfo();
			String salt = oConvertUtils.randomGen(8);
			user.setSalt(salt);
			String passwordEncode = PasswordUtil.encrypt(loginame, password, salt);
			user.setPwd(passwordEncode);
			user.setStatus(0);
			//user.setPwd(password);
			user.setUpdateTime(new Date());
			//user.setCreateTime(new Date());

			Wrapper<UcenterUserinfo> wrapperq=new QueryWrapper<UcenterUserinfo>()
					.eq("uid",uid)
					;
			if(sysUserService.update(user,wrapperq)) {
				result.setResult("1");
				result.setMessage("更新成功！");

			}else {
				result.error500("接口异常");
			}
		}else {
			result.setResult("0");
			result.setMessage("俩次密码不相同！");

		}
		return result;
	}
	/**
	 * 获取访问量
	 * @return
	 */
	@GetMapping("loginfo")
	public Result<JSONObject> loginfo() {
		Result<JSONObject> result = new Result<JSONObject>();
		JSONObject obj = new JSONObject();
		//update-begin--Author:zhangweijian  Date:20190428 for：传入开始时间，结束时间参数
		// 获取一天的开始和结束时间
		Calendar calendar = new GregorianCalendar();
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		Date dayStart = calendar.getTime();
		calendar.add(Calendar.DATE, 1);
		Date dayEnd = calendar.getTime();
		// 获取系统访问记录
		/*
		Long totalVisitCount = logService.findTotalVisitCount();
		obj.put("totalVisitCount", totalVisitCount);
		Long todayVisitCount = logService.findTodayVisitCount(dayStart,dayEnd);
		obj.put("todayVisitCount", todayVisitCount);
		Long todayIp = logService.findTodayIp(dayStart,dayEnd);
		//update-end--Author:zhangweijian  Date:20190428 for：传入开始时间，结束时间参数
		obj.put("todayIp", todayIp);
		*/
		result.setResult(obj);
		result.success("登录成功");
		return result;
	}
	
	/**
	 * 获取访问量
	 * @return
	 */
	@GetMapping("visitInfo")
	public Result<List<Map<String,Object>>> visitInfo() {
		Result<List<Map<String,Object>>> result = new Result<List<Map<String,Object>>>();
		Calendar calendar = new GregorianCalendar();
		calendar.set(Calendar.HOUR_OF_DAY,0);
        calendar.set(Calendar.MINUTE,0);
        calendar.set(Calendar.SECOND,0);
        calendar.set(Calendar.MILLISECOND,0);
        calendar.add(Calendar.DAY_OF_MONTH, 1);
        Date dayEnd = calendar.getTime();
        calendar.add(Calendar.DAY_OF_MONTH, -7);
        Date dayStart = calendar.getTime();
        //List<Map<String,Object>> list = logService.findVisitCount(dayStart, dayEnd);
		//result.setResult(oConvertUtils.toLowerCasePageList(list));
		return result;
	}
	
	
	/**
	 * 登陆成功选择用户当前部门
	 * @param user
	 * @return
	 */
	@RequestMapping(value = "/selectDepart", method = RequestMethod.PUT)
	public Result<JSONObject> selectDepart(@RequestBody UcenterUserinfo user) {
		Result<JSONObject> result = new Result<JSONObject>();
		//String username = user.getUsername();
		//if(oConvertUtils.isEmpty(username)) {
		//	LoginUser sysUser = (LoginUser)SecurityUtils.getSubject().getPrincipal();
		//	username = sysUser.getUsername();
		//}
		//String orgCode= user.getOrgCode();
		//this.sysUserService.updateUserDepart(username, orgCode);
		//UcenterUserinfo sysUser = sysUserService.getUserByName(username);
		//JSONObject obj = new JSONObject();
		//obj.put("userInfo", sysUser);
		//result.setResult(obj);
		return result;
	}

	/**
	 * 短信登录接口
	 * 
	 * @param jsonObject
	 * @return
	 */
	@PostMapping(value = "/sms")
	public Result<String> sms(@RequestBody JSONObject jsonObject) {
		Result<String> result = new Result<String>();
		String mobile = jsonObject.get("mobile").toString();
		String smsmode=jsonObject.get("smsmode").toString();
		log.info(mobile);	
		Object object = redisUtil.get(mobile);
		if (object != null) {
			result.setMessage("验证码10分钟内，仍然有效！");
			result.setSuccess(false);
			return result;
		}

		//随机数
		String captcha = RandomUtil.randomNumbers(6);
		JSONObject obj = new JSONObject();
    	obj.put("code", captcha);
		try {
			boolean b = false;
			//注册模板
			if (CommonConstant.SMS_TPL_TYPE_1.equals(smsmode)) {
				UcenterUserinfo sysUser = sysUserService.getUserByPhone(mobile);
				if(sysUser!=null) {
					result.error500(" 手机号已经注册，请直接登录！");
					//sysBaseAPI.addLog("手机号已经注册，请直接登录！", CommonConstant.LOG_TYPE_1, null);
					return result;
				}
				//b = DySmsHelper.sendSms(mobile, obj, DySmsEnum.REGISTER_TEMPLATE_CODE);
			}else {
				//登录模式，校验用户有效性
				UcenterUserinfo sysUser = sysUserService.getUserByPhone(mobile);
				result = sysUserService.checkUserIsEffective(sysUser);
				if(!result.isSuccess()) {
					return result;
				}
				
				/**
				 * smsmode 短信模板方式  0 .登录模板、1.注册模板、2.忘记密码模板
				 */
				if (CommonConstant.SMS_TPL_TYPE_0.equals(smsmode)) {
					//登录模板
					//b = DySmsHelper.sendSms(mobile, obj, DySmsEnum.LOGIN_TEMPLATE_CODE);
				} else if(CommonConstant.SMS_TPL_TYPE_2.equals(smsmode)) {
					//忘记密码模板
					//b = DySmsHelper.sendSms(mobile, obj, DySmsEnum.FORGET_PASSWORD_TEMPLATE_CODE);
				}
			}

			if (b == false) {
				result.setMessage("短信验证码发送失败,请稍后重试");
				result.setSuccess(false);
				return result;
			}
			//验证码10分钟内有效
			redisUtil.set(mobile, captcha, 600);
			//update-begin--Author:scott  Date:20190812 for：issues#391
			//result.setResult(captcha);
			//update-end--Author:scott  Date:20190812 for：issues#391
			result.setSuccess(true);

		//} catch (ClientException e) {
		} catch (Exception e) {
			e.printStackTrace();
			result.error500(" 短信接口未配置，请联系管理员！");
			return result;
		}
		return result;
	}
	

	/**
	 * 手机号登录接口
	 * 
	 * @param jsonObject
	 * @return
	 */
	@PostMapping("/phoneLogin")
	public Result<JSONObject> phoneLogin(@RequestBody JSONObject jsonObject) {
		Result<JSONObject> result = new Result<JSONObject>();
		String phone = jsonObject.getString("mobile");
		
		//校验用户有效性
		UcenterUserinfo sysUser = sysUserService.getUserByPhone(phone);
		result = sysUserService.checkUserIsEffective(sysUser);
		if(!result.isSuccess()) {
			return result;
		}
		
		String smscode = jsonObject.getString("captcha");
		Object code = redisUtil.get(phone);
		if (!smscode.equals(code)) {
			result.setMessage("手机验证码错误");
			return result;
		}
		//用户信息
		userInfo(sysUser, result);
		//添加日志
		//sysBaseAPI.addLog("用户名: " + sysUser.getUsername() + ",登录成功！", CommonConstant.LOG_TYPE_1, null);

		return result;
	}


	/**
	 * 用户信息
	 *
	 * @param sysUser
	 * @param result
	 * @return
	 */
	private Result<JSONObject> userInfo(UcenterUserinfo sysUser, Result<JSONObject> result) {
		String syspassword = sysUser.getPwd();
		String username = sysUser.getUsername();
		// 生成token
		String token = JwtUtil.sign(username, syspassword);
		
		//redisUtil.set(CommonConstant.PREFIX_USER_LOGIN + username, token);
		// 设置超时时间
		//redisUtil.expire(CommonConstant.PREFIX_USER_LOGIN + username, JwtUtil.EXPIRE_TIME / 1000);
		
		redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + username, token);
		// 设置超时时间
		redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + username, JwtUtil.REDIS_EXPIRE_TIME );

		// 获取用户部门信息
		JSONObject obj = new JSONObject();
		/*
		List<SysDepart> departs = sysDepartService.queryUserDeparts(sysUser.getId());
		obj.put("departs", departs);
		if (departs == null || departs.size() == 0) {
			obj.put("multi_depart", 0);
		} else if (departs.size() == 1) {
			sysUserService.updateUserDepart(username, departs.get(0).getOrgCode());
			obj.put("multi_depart", 1);
		} else {
			obj.put("multi_depart", 2);
		}
		*/
		obj.put("token", token);
		obj.put("userInfo", sysUser);
		result.setResult(obj);
		result.success("登录成功");
		return result;
	}

	/**
	 * 获取加密字符串
	 * @return
	 */
	@GetMapping(value = "/getEncryptedString")
	public Result<Map<String,String>> getEncryptedString(){
		Result<Map<String,String>> result = new Result<Map<String,String>>();
		Map<String,String> map = new HashMap<String,String>();
		//map.put("key", EncryptedString.key);
		//map.put("iv",EncryptedString.iv);
		result.setResult(map);
		return result;
	}

}